package common

import (
	"fmt"
	"gorm.io/gorm"
	"seven-admin/app/admin/schemas/req"
	"seven-admin/app/admin/schemas/resp"
	"seven-admin/app/collection/common"
	"seven-admin/core/response"
	"strings"
)

type DictionariesService interface {
	List(page req.PageReq, sqlReq req.CommonDictListReq, auth *req.AuthReq) (response.PageResp, error)
	Detail(id uint, auth *req.AuthReq) (interface{}, error)
	Add(addReq req.CommonDictAddReq, auth *req.AuthReq) error
	Edit(editReq req.CommonDictEditReq, auth *req.AuthReq) error
	Del(id uint, auth *req.AuthReq) error
	Query(sqlReq req.CommonDictListReq, auth *req.AuthReq) (interface{}, error)
	Types(auth *req.AuthReq) (interface{}, error)
}

type dictionariesService struct {
	db *gorm.DB
}

func (d dictionariesService) List(page req.PageReq, req req.CommonDictListReq, auth *req.AuthReq) (res response.PageResp, e error) {
	limit := page.PageSize
	offset := page.PageSize * (page.PageNo - 1)
	sql := d.db.Model(&common.Dictionaries{})
	sql = sql.Where("tenant_id = ?", auth.TenantId)
	if len(req.Type) > 0 {
		sql = sql.Where("type = ?", req.Type)
	}
	if len(req.Value) > 0 {
		sql = sql.Where("value like ?", "%"+req.Value+"%")
	}
	var total int64
	var list []common.Dictionaries
	if err := sql.Count(&total).Error; err != nil {
		return res, err
	}
	if err := sql.Limit(limit).Offset(offset).Find(&list).Error; err != nil {
		return res, err
	}
	var result []resp.CommonDictResp
	response.Copy(&result, list)
	return response.PageResp{
		PageNo:   page.PageNo,
		PageSize: page.PageSize,
		Count:    total,
		Lists:    result,
	}, nil
}

func (d dictionariesService) Detail(id uint, auth *req.AuthReq) (interface{}, error) {
	var res common.Dictionaries
	sql := d.db.Model(&common.Dictionaries{})
	sql = sql.Where("tenant_id = ?", auth.TenantId)
	err := sql.Where("id = ?", id).First(&res).Error
	if err != nil {
		return nil, err
	}
	return res, nil
}

func (d dictionariesService) Add(addReq req.CommonDictAddReq, auth *req.AuthReq) error {
	var dict common.Dictionaries
	var count int64
	sql := d.db.Model(&common.Dictionaries{})
	sql = sql.Where("tenant_id = ?", auth.TenantId)
	sql.Where("type = ? and value = ?", addReq.Type, addReq.Value).Count(&count)
	if count > 0 {
		return fmt.Errorf("相同的字典值已存在")
	}
	response.Copy(&dict, addReq)
	dict.TenantId = auth.TenantId
	return d.db.Create(&dict).Error
}

func (d dictionariesService) Edit(editReq req.CommonDictEditReq, auth *req.AuthReq) error {
	var dict common.Dictionaries
	var count int64
	sql := d.db.Model(&common.Dictionaries{})
	sql = sql.Where("tenant_id = ?", auth.TenantId)
	sql.Where("type = ? and value = ? and id != ?", editReq.Type, editReq.Value, editReq.ID).Count(&count)
	if count > 0 {
		return fmt.Errorf("相同的字典值已存在")
	}
	response.Copy(&dict, editReq)
	if auth.IsSuperAdmin {
		dict.TenantId = editReq.TenantId
	}
	return d.db.Model(&dict).Where("id = ?", editReq.ID).Updates(&dict).Error
}

func (d dictionariesService) Del(id uint, auth *req.AuthReq) error {
	sql := d.db.Model(&common.Dictionaries{})
	sql = sql.Where("tenant_id = ?", auth.TenantId)
	var dict common.Dictionaries
	if err := sql.Where("id = ?", id).First(&dict).Error; err != nil {
		return err
	}
	if auth.TenantId != dict.TenantId && !auth.IsSuperTenant {
		return fmt.Errorf("无权限,不能删除！")
	}
	return sql.Where("id = ?", id).Delete(&common.Dictionaries{}).Error
}

func (d dictionariesService) Query(sqlReq req.CommonDictListReq, auth *req.AuthReq) (interface{}, error) {
	if len(sqlReq.Type) == 0 {
		return nil, nil
	}
	// 分割字符串
	types := strings.Split(sqlReq.Type, ",")
	data := make(map[string]interface{})
	sql := d.db.Model(&common.Dictionaries{})
	sql = sql.Where("tenant_id = ?", auth.TenantId)
	for _, t := range types {
		var list []common.Dictionaries
		if err := sql.Where("type = ?", t).Find(&list).Error; err != nil {
			return nil, err
		}
		var d []resp.CommonSelectResp
		for _, l := range list {
			d = append(d, resp.CommonSelectResp{
				Label: l.Value,
				Value: l.Value,
			})
		}
		data[t] = d
	}
	return data, nil
}
func (d dictionariesService) Types(auth *req.AuthReq) (interface{}, error) {
	var list []common.Dictionaries
	sql := d.db.Model(&common.Dictionaries{})
	sql = sql.Where("tenant_id = ?", auth.TenantId)
	if err := sql.Select("DISTINCT type").Find(&list).Error; err != nil {
		return nil, err
	}
	// [{"label": "type", "value": "type"}]
	var result []resp.CommonSelectResp
	for _, l := range list {
		result = append(result, resp.CommonSelectResp{
			Label: l.Type,
			Value: l.Type,
		})
	}
	return result, nil

}

func NewDictionariesService(db *gorm.DB) DictionariesService {
	return &dictionariesService{db: db}
}
